package site.wetsion.galio.sdk.utils;

import com.alibaba.fastjson.JSON;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import org.springframework.web.client.RestTemplate;
import site.wetsion.galio.sdk.common.GalioClientDetailsProperties;
import site.wetsion.galio.sdk.common.GalioOauthAccessToken;
import site.wetsion.galio.sdk.common.GalioOauthConstant;
import site.wetsion.galio.sdk.common.OauthClientContext;
import java.util.Date;
import java.util.Objects;

/**
 * 提供对授权码模式的操作
 *
 * @author weixin
 * @version 1.0
 * @CLassName AuthorizationCodeProvider
 * @date 2019/3/20 2:46 PM
 */
public class AuthorizationCodeProvider {

    private final static Logger logger = LoggerFactory.getLogger(AuthorizationCodeProvider.class);

    private final static String AUTHORIZATION_CODE = "authorization_code";

    private GalioClientDetailsProperties galioClientDetailsProperties;

    private AccessTokenHolderWrapper accessTokenHolderWrapper;

    public AuthorizationCodeProvider(GalioClientDetailsProperties galioClientDetailsProperties) {
        this.galioClientDetailsProperties = galioClientDetailsProperties;
    }

    public AuthorizationCodeProvider(GalioClientDetailsProperties galioClientDetailsProperties,
                                     AccessTokenHolderWrapper accessTokenHolderWrapper) {
        this.accessTokenHolderWrapper = accessTokenHolderWrapper;
        this.galioClientDetailsProperties = galioClientDetailsProperties;
    }

    public boolean handleCode(String code, String redirectUri, OauthClientContext oauthClientContext) {
        GalioOauthAccessToken accessToken = null;
        RestTemplate restTemplate = new RestTemplate();
        MultiValueMap<String, String> params= new LinkedMultiValueMap<>();
        params.add(GalioOauthConstant.GRANT_TYPE, AUTHORIZATION_CODE);
        params.add(GalioOauthConstant.CODE, code);
        params.add(GalioOauthConstant.REDIRECT_URI, redirectUri);
        params.add(GalioOauthConstant.CLIENT_ID, galioClientDetailsProperties.getClientId());
        params.add(GalioOauthConstant.CLIENT_SECRET, galioClientDetailsProperties.getClientSecret());
        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);
        HttpEntity<MultiValueMap<String, String>> entity = new HttpEntity<>(params, headers);
        ResponseEntity<String> responseEntity = null;
        try {
            responseEntity = restTemplate.postForEntity(
                    galioClientDetailsProperties.getAccessTokenUrl(), entity, String.class);
            accessToken = JSON.parseObject(responseEntity.getBody(), GalioOauthAccessToken.class);
            if (Objects.nonNull(accessToken)) {
                accessToken.setExpiration(new Date(System.currentTimeMillis() + accessToken.getValidity() * 1000L));
            }
            oauthClientContext.setAccessToken(accessToken);
            accessTokenHolderWrapper.save(accessToken.getAccessToken(), accessToken);
            return true;
        } catch (Exception e) {
            logger.info("根据授权码远程auth获取token认证失败: {}", e.getMessage());
        }
        return false;
    }
}
